package com.athena.framework.annotation;

import cn.hutool.core.util.ReflectUtil;
import com.athena.framework.beanfactory.BeanFactory;
import com.athena.framework.beanfactory.DefaultBeanFactory;
import com.athena.framework.exception.BeanException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

/**
 * 解析Autowired注解
 * 为添加有Autowired注解的字段自动填充值
 */
public class AutowiredParsing implements AnnotationParsing {

    private final static Logger logger = LoggerFactory.getLogger(AutowiredParsing.class);
    private BeanFactory beanFactory = DefaultBeanFactory.creatBeanFactory();

    /**
     * 开始填充值
     */
    @Override
    public void parsing() {
        if (logger.isInfoEnabled()){
            logger.info("开始填充属性...");
        }
        //遍历被托管的类
        beanFactory.forEach((name, obj) -> {
            //查找被托管类型是否有被Autowired注解的属性
            List<Field> fieldList = parsingField(obj);
            //遍历属性，为起找到相对应的值
            fieldList.forEach(field -> {
                field.setAccessible(true);
                Autowired annotation = field.getAnnotation(Autowired.class);
                String beanName = annotation.value();
                Object bean;
                if (beanName.length() == 0) {
                    beanName = field.getType().getName();
                    bean = beanFactory.getBean(beanName);
                    if (bean == null) {
                        //如果无法根据名称查找到bean，那么就遍历查找其子类或实现类
                        Map<String, Object> beans = beanFactory.findSubclass(field.getType());
                        if (beans.size() == 0) {
                            throw new BeanException("未托管" + field.getType().getName() + "的子类或实现类");
                        } else if (beans.size() == 1) {
                            for (String s : beans.keySet()) {
                                bean = beans.get(s);
                            }
                        } else {
                            throw new BeanException("找到了多个被托管的" + field.getType() + "的子类或实现类，请设置value，指明填充哪一个");
                        }
                    }
                } else {
                    bean = beanFactory.getBean(beanName);
                    if (bean == null) {
                        throw new BeanException("未托管:" + bean + "实例");
                    }
                }
                try {
                    field.set(obj, bean);
                } catch (IllegalAccessException e) {
                    String msg = "设置属性值失败：" + obj.getClass().getName() + "." + field.getName() + "\r\n";
                    logger.error(msg);
                    throw new BeanException(msg);
                }
            });
        });
    }

    /**
     * 查找被托管类型是否有被Autowired注解的属性
     *
     * @param obj
     * @return
     */
    private List<Field> parsingField(Object obj) {
        List<Field> fieldList = new LinkedList<>();
        Field[] fields = ReflectUtil.getFields(obj.getClass());
        for (int i = 0; i < fields.length; i++) {
            Autowired annotation = fields[i].getAnnotation(Autowired.class);
            if (annotation != null) {
                fieldList.add(fields[i]);
            }
        }
        return fieldList;
    }
}
